#pragma once
#include <iostream>
#include <string>
#include <functional>
#define LISTENCONNECTION 0
#define NORMALCONNECTION 1
#include"Socket.hpp"
class Connection;
class Reactor;
using handler_t = std::function<void(Connection *conn)>;
class Connection
{
public:
    Connection(int sockfd) :_sockfd(sockfd){}
    void RegisterHandler(handler_t recver,handler_t sender,handler_t excepter)
    {
        _handler_recver = recver;
        _handler_sender = sender;
        _handler_excepter = excepter;
    }
    int Sockfd()
    {
        return _sockfd;
    }
    void SetType(int type)
    {
        _type = type;
    }
    void SetEvents(uint32_t ev)
    {
        _events = ev;
    }
    uint32_t Events()
    {
        return _events;
    }
    void SetReactor(Reactor* R)
    {
        _R = R;
    }
    void SetAddr(const InetAddr &addr)
    {
        _addr = addr;
    }
    int Type()
    {
        return _type;
    }
    void AppendInbuffer(const std::string &instr)
    {
        _inbuffer += instr;
    }
    void AppendOutbuffer(const std::string &outstr)
    {
        _outbuffer += outstr;
    }
    std::string &Inbuff()
    {
        return _inbuffer;
    }    
    std::string &Outbuff()
    {
        return _outbuffer;
    }
    void DiscardOutbuffer(int n)
    {
        _outbuffer.erase(0, n);
    }
    void Close()
    {
        if(_sockfd>0)
            ::close(_sockfd);
    }
    ~Connection() {
    LOG(INFO, "Connection %d destroyed, _R=%p\n", _sockfd, _R);
}

private:
    int _sockfd;
    uint32_t _events;
    std::string _inbuffer;
    std::string _outbuffer;
    int _type;

public:
    handler_t _handler_recver;
    handler_t _handler_sender;
    handler_t _handler_excepter;
    InetAddr _addr;

    Reactor *_R;
};